package com.fsm.system.serviceImpl;

import com.alibaba.excel.EasyExcel;
import com.fsm.common.log.entity.TSystemLoginLog;
import com.fsm.common.log.entity.TSystemOperationLog;
import com.fsm.common.log.entity.excelbo.TSystemLoginLogBo;
import com.fsm.common.log.entity.excelbo.TSystemOperationLogBo;
import com.fsm.common.log.entity.table.TSystemLoginLogTable;
import com.fsm.common.log.mapper.TSystemLoginLogMapper;
import com.fsm.common.tools.Result.Result;
import com.fsm.common.tools.util.DateUtils;
import com.fsm.common.tools.util.PoToDTO;
import com.fsm.system.entity.TSystemUser;
import com.fsm.system.entity.table.TSystemUserTable;
import com.fsm.system.mapper.SystemUserMapper;
import com.fsm.system.service.TSystemLoginLogService;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 *  登录日志接口。
 *
 * @author 翻山鸣
 * @since 2024/04/20
 */
@Service
public class TSystemLoginLogServiceImpl extends ServiceImpl<TSystemLoginLogMapper, TSystemLoginLog> implements TSystemLoginLogService {

    @Autowired
    private SystemUserMapper oSystemUserMapper;

    /**
     * 公共整合查询条件
     * @param tSystemLoginLog
     * @return
     */
    private static QueryWrapper getSelectQueryWrapper(TSystemLoginLog tSystemLoginLog){
        QueryWrapper queryWrapper = new QueryWrapper();
        //判断是否传入查询时间
        if(tSystemLoginLog.getQueryBeginTime() != null && tSystemLoginLog.getQueryEndTime() != null){
            queryWrapper.where(TSystemLoginLogTable.T_SYSTEM_LOGIN_LOG.LOGIN_TIME.between(tSystemLoginLog.getQueryBeginTime(),tSystemLoginLog.getQueryBeginTime()));
        }
        queryWrapper.orderBy("login_time desc");
        return queryWrapper;
    }

    /**
     * 分页查询登录日志
     *
     * @param tSystemLoginLog
     * @return 分页对象
     */
    @Override
    public Result pageTSystemLoginLog(TSystemLoginLog tSystemLoginLog) throws Exception {
        QueryWrapper queryWrapper = getSelectQueryWrapper(tSystemLoginLog);
        Page<TSystemLoginLog> tSystemLoginLogPage = this.getMapper().paginateWithRelations(tSystemLoginLog.getPage(),tSystemLoginLog.getLimit(),queryWrapper);
        List<TSystemLoginLog> oTSystemLoginLogList = tSystemLoginLogPage.getRecords();
        if(CollectionUtils.isNotEmpty(oTSystemLoginLogList)){
            //获取查到的用户ID集合
            Set<String> oSystemUserIdList = new HashSet<>();
            oTSystemLoginLogList.forEach(item->{oSystemUserIdList.add(item.getUserId());});
            //获取查到的用户集合
            QueryWrapper qwSystemUser = new QueryWrapper();
            qwSystemUser.where(TSystemUserTable.T_SYSTEM_USER.ID.in(oSystemUserIdList));
            List<TSystemUser> oSystemUserList = oSystemUserMapper.selectListByQuery(qwSystemUser);
            if(CollectionUtils.isNotEmpty(oSystemUserList)){
                //重组
                Map<String,String> map = new HashMap<>();
                oSystemUserList.forEach(item->{map.put(item.getId(),item.getName());});
                //获取用户名
                oTSystemLoginLogList.forEach(item->{
                    if(map.containsKey(item.getUserId())){
                        item.setUserName(map.get(item.getUserId()));
                    }
                });
            }
        }
        return Result.ok(oTSystemLoginLogList,tSystemLoginLogPage.getTotalRow());
    }

    /**
     * 导出登录日志
     *
     * @param tSystemLoginLog
     * @return 分页对象
     */
    @Override
    public Result uploadTSystemLoginLogData(TSystemLoginLog tSystemLoginLog, HttpServletResponse response) throws Exception {
        QueryWrapper queryWrapper = getSelectQueryWrapper(tSystemLoginLog);
        List<TSystemLoginLog> oTSystemLoginLogList = this.getMapper().selectListByQuery(queryWrapper);
        if(CollectionUtils.isNotEmpty(oTSystemLoginLogList)){
            //获取查到的用户ID集合
            Set<String> oSystemUserIdList = new HashSet<>();
            oTSystemLoginLogList.forEach(item->{
                oSystemUserIdList.add(item.getUserId());
                //转换成BO

            });
            //获取查到的用户集合
            QueryWrapper qwSystemUser = new QueryWrapper();
            qwSystemUser.where(TSystemUserTable.T_SYSTEM_USER.ID.in(oSystemUserIdList));
            List<TSystemUser> oSystemUserList = oSystemUserMapper.selectListByQuery(qwSystemUser);
            if(CollectionUtils.isNotEmpty(oSystemUserList)){
                //重组
                Map<String,String> map = new HashMap<>();
                oSystemUserList.forEach(item->{map.put(item.getId(),item.getName());});
                //获取用户名
                oTSystemLoginLogList.forEach(item->{
                    if(map.containsKey(item.getUserId())){
                        item.setUserName(map.get(item.getUserId()));
                    }
                });
            }
        }
        //创建转换成BO
        //PoToDto
        List<TSystemLoginLogBo> oTSystemLoginLogBoList = (List<TSystemLoginLogBo>) PoToDTO.poToDtoList(oTSystemLoginLogList,new TSystemLoginLogBo());

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("操作日志信息表", "UTF-8").replaceAll("\\+", "%20");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=" + fileName + ".xlsx");
        OutputStream outputStream = response.getOutputStream();
        EasyExcel.write(outputStream, TSystemLoginLogBo.class)
                .sheet("操作日志信息")
                .doWrite(oTSystemLoginLogBoList);
        return Result.ok();
    }

    /**
     * 清除登录日志
     * 放开@Scheduled注解后，每年底除登录日志，保留近一个月数据
     *
     * @param
     * @return 分页对象
     */
    @Override
    @Transactional
    public void cleanTSystemLoginLog() throws Exception {
        //获取上月的开始时间和结束时间
        Map<String,Date> map = DateUtils.getLastMonth();
        //清除
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(TSystemLoginLogTable.T_SYSTEM_LOGIN_LOG.LOGIN_TIME.lt(map.get("beginTime")));
        this.getMapper().deleteByQuery(queryWrapper);
    }

}
